from flask import request, jsonify, g
from flask_jwt_extended import jwt_required
import datetime
from bson import ObjectId

from app.api.v1 import api_bp
from app import mongo
from app.utils.auth import permission_required
from app.schemas.drug import DrugSchema, DrugUpdateSchema
from app.utils.common import normalize_data, paginate, generate_id

@api_bp.route('/drugs', methods=['GET'])
@jwt_required()
@permission_required('drug:read')
def get_drugs():
    """获取药品列表"""
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 20, type=int)
    sort_by = request.args.get('sortBy', 'name')
    order = request.args.get('order', 'asc')
    
    # 构建查询条件
    query = {}
    
    # 按名称搜索
    name = request.args.get('name')
    if name:
        query['$or'] = [
            {'name': {'$regex': name, '$options': 'i'}},
            {'genericName': {'$regex': name, '$options': 'i'}}
        ]
    
    # 按分类搜索
    category = request.args.get('category')
    if category:
        query['category'] = category
    
    # 按状态筛选
    status = request.args.get('status')
    if status:
        query['status'] = status
    
    # 按处方药筛选
    is_prescription = request.args.get('isPrescription')
    if is_prescription is not None:
        is_prescription = is_prescription.lower() == 'true'
        query['properties.isPrescription'] = is_prescription
    
    # 按管制药品筛选
    is_controlled = request.args.get('isControlled')
    if is_controlled is not None:
        is_controlled = is_controlled.lower() == 'true'
        query['properties.isControlled'] = is_controlled
    
    # 确定排序
    sort_direction = 1 if order.lower() == 'asc' else -1
    
    # 获取数据
    drugs_cursor = mongo.db.drugs.find(query).sort(sort_by, sort_direction)
    
    # 分页
    paginated_data = paginate(drugs_cursor, page, limit)
    
    # 标准化数据
    normalized_items = [normalize_data(item) for item in paginated_data['items']]
    
    return jsonify({
        'success': True,
        'data': {
            'total': paginated_data['total'],
            'page': paginated_data['page'],
            'limit': paginated_data['per_page'],
            'drugs': normalized_items
        }
    }), 200

@api_bp.route('/drugs', methods=['POST'])
@jwt_required()
@permission_required('drug:create')
def create_drug():
    """创建新药品"""
    # 验证请求数据
    schema = DrugSchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 检查药品编码是否已存在
    if mongo.db.drugs.find_one({'drugCode': data['drugCode']}):
        return jsonify({
            'success': False,
            'message': '该药品编码已存在'
        }), 400
    
    # 检查药品分类是否有效
    valid_categories = ['西药', '中成药', '中药饮片', '生物制品']
    if data['category'] not in valid_categories:
        return jsonify({
            'success': False,
            'message': '无效的药品分类',
            'validCategories': valid_categories
        }), 400
    
    # 设置默认属性
    if 'properties' not in data:
        data['properties'] = {}
    
    if 'usage' not in data:
        data['usage'] = {}
    
    # 设置创建时间和更新时间
    now = datetime.datetime.utcnow()
    data['createdAt'] = now
    data['updatedAt'] = now
    
    # 保存到数据库
    result = mongo.db.drugs.insert_one(data)
    
    return jsonify({
        'success': True,
        'message': '药品创建成功',
        'data': {
            'id': str(result.inserted_id),
            'drugCode': data['drugCode'],
            'name': data['name'],
            'createdAt': now.isoformat()
        }
    }), 201

@api_bp.route('/drugs/<id>', methods=['GET'])
@jwt_required()
@permission_required('drug:read')
def get_drug(id):
    """获取单个药品详情"""
    # 尝试按ID查找
    drug = None
    
    # 如果是有效的ObjectId，按_id查找
    if ObjectId.is_valid(id):
        drug = mongo.db.drugs.find_one({'_id': ObjectId(id)})
    
    # 如果没找到，尝试按drugCode查找
    if not drug:
        drug = mongo.db.drugs.find_one({'drugCode': id})
    
    if not drug:
        return jsonify({
            'success': False,
            'message': '药品不存在'
        }), 404
    
    # 标准化数据
    normalized_drug = normalize_data(drug)
    
    # 获取库存信息
    inventory_list = []
    inventories = mongo.db.drug_inventory.find({'drugId': str(drug['_id'])})
    
    total_quantity = 0
    for inv in inventories:
        total_quantity += inv.get('quantity', 0)
        inventory_list.append(normalize_data(inv))
    
    normalized_drug['inventory'] = {
        'totalQuantity': total_quantity,
        'details': inventory_list
    }
    
    return jsonify({
        'success': True,
        'data': normalized_drug
    }), 200

@api_bp.route('/drugs/<id>', methods=['PUT'])
@jwt_required()
@permission_required('drug:update')
def update_drug(id):
    """更新药品信息"""
    # 验证请求数据
    schema = DrugUpdateSchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 查找药品
    drug = None
    if ObjectId.is_valid(id):
        drug = mongo.db.drugs.find_one({'_id': ObjectId(id)})
    
    if not drug:
        drug = mongo.db.drugs.find_one({'drugCode': id})
    
    if not drug:
        return jsonify({
            'success': False,
            'message': '药品不存在'
        }), 404
    
    # 准备更新数据
    update_data = data.copy()
    update_data['updatedAt'] = datetime.datetime.utcnow()
    
    # 更新数据库
    result = mongo.db.drugs.update_one(
        {'_id': drug['_id']},
        {'$set': update_data}
    )
    
    if result.modified_count == 0:
        return jsonify({
            'success': False,
            'message': '药品信息更新失败'
        }), 500
    
    return jsonify({
        'success': True,
        'message': '药品信息更新成功',
        'data': {
            'id': str(drug['_id']),
            'drugCode': drug['drugCode'],
            'name': data.get('name', drug['name']),
            'updatedAt': update_data['updatedAt'].isoformat()
        }
    }), 200

@api_bp.route('/drugs/<id>', methods=['DELETE'])
@jwt_required()
@permission_required('drug:delete')
def delete_drug(id):
    """删除药品（通常只是将药品标记为禁用）"""
    # 查找药品
    drug = None
    if ObjectId.is_valid(id):
        drug = mongo.db.drugs.find_one({'_id': ObjectId(id)})
    
    if not drug:
        drug = mongo.db.drugs.find_one({'drugCode': id})
    
    if not drug:
        return jsonify({
            'success': False,
            'message': '药品不存在'
        }), 404
    
    # 检查药品是否有库存
    inventory = mongo.db.drug_inventory.find_one({'drugId': str(drug['_id']), 'quantity': {'$gt': 0}})
    if inventory:
        return jsonify({
            'success': False,
            'message': '药品仍有库存，无法删除'
        }), 400
    
    # 检查药品是否被处方引用
    prescription = mongo.db.prescriptions.find_one({'items.drugId': str(drug['_id'])})
    if prescription:
        # 实际上我们只是将药品标记为禁用，而不是真正删除
        result = mongo.db.drugs.update_one(
            {'_id': drug['_id']},
            {
                '$set': {
                    'status': '禁用',
                    'updatedAt': datetime.datetime.utcnow()
                }
            }
        )
        
        return jsonify({
            'success': True,
            'message': '药品被处方引用，已标记为禁用',
            'data': None
        }), 200
    
    # 如果没有被引用，可以真正删除
    result = mongo.db.drugs.delete_one({'_id': drug['_id']})
    
    if result.deleted_count == 0:
        return jsonify({
            'success': False,
            'message': '药品删除失败'
        }), 500
    
    return jsonify({
        'success': True,
        'message': '药品删除成功',
        'data': None
    }), 200

@api_bp.route('/drugs/categories', methods=['GET'])
@jwt_required()
def get_drug_categories():
    """获取所有药品分类"""
    # 从drug_categories集合获取预设的药品分类
    categories = []
    drug_categories = mongo.db.drug_categories.find({}, {'name': 1, 'code': 1, 'description': 1, '_id': 1})
    
    for category in drug_categories:
        categories.append({
            'id': str(category['_id']),
            'name': category['name'],
            'code': category['code'],
            'description': category.get('description', '')
        })
    
    # 如果没有找到分类（可能是新系统），则返回默认分类
    if not categories:
        categories = [
            {'name': '西药', 'code': 'XY', 'description': '西药类别'},
            {'name': '中成药', 'code': 'ZCY', 'description': '中成药类别'},
            {'name': '中药饮片', 'code': 'ZYYP', 'description': '中药饮片类别'},
            {'name': '生物制品', 'code': 'SWZP', 'description': '生物制品类别'}
        ]
    
    return jsonify({
        'success': True,
        'data': {
            'categories': categories
        }
    }), 200 